#include <iostream>
#include <string>
#include <asio.hpp>
#include <thread>

using namespace std;
using asio::ip::tcp;

const int max_length = 1024;

void session(tcp::socket sock)
{
	try {
		for (; ;) {
			char data[max_length];
			asio::error_code error;
			size_t length = sock.read_some(asio::buffer(data), error);
			if (error == asio::error::eof) {
				break; // Connectoin closd cleanly by peer.
			}
			else if (error) {
				throw asio::system_error(error); // Some other error.
			}

			asio::write(sock, asio::buffer(data, length));
		}
	}
	catch (std::exception& e) {
		std::cerr << "Exception in thread: " << e.what() << "\n";
	}
}

void server(asio::io_context& io_context, unsigned short port)
{
	tcp::acceptor a(io_context, tcp::endpoint(tcp::v4(), port));
	for (; ;) {
		std::thread(session, a.accept()).detach();
	}
}

// blocking tcp echo server
// https://think-async.com/Asio/asio-1.22.1/src/examples/cpp11/echo/blocking_tcp_echo_server.cpp

int main(int argc, char* argv[])
{
	unsigned short port = 2008;
	try {
		//if (argc != 2) {
		//	std::cerr << "Usage: blocking_tcp_echo_server <port>\n";
		//	return 1;

		//	asio::io_context io_context;
		//	server(io_context, std::atoi(argv[1]));
		//}
		asio::io_context io_context;
		server(io_context, port);
	}
	catch (std::exception& e) {
		std::cerr << "Exception: " << e.what() << "\n";
	}

	return 0;
}
